package me.twoday.library.mine.component;

import java.util.ArrayList;

import me.twoday.library.mine.common.ActivityUtil;
import me.twoday.library.mine.common.MessageUtil;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;

/**
 * listView 사용시 필요한 모든것들을 제공하는 Handler클래스(상속해서 사용) 
 * 
 * @author 김학성
 * @since 2012. 4. 24.
 */
public abstract class BaseListHandler implements OnScrollListener
{
	private static final String TAG = "BaseListHandler";
	protected Activity mParentActivity;
	protected BaseListView mListView;
	protected BaseListAdapter mListAdapter;
	protected LayoutInflater mInflater;
	protected View mHeaderView;
	protected View mFooterView;
	private boolean mFlagListView;
	private boolean mIsLoadedHeaderView;
	protected boolean mIsWriteActivityForResult;
	
	/**
	 * 기본 생성자
	 * 
	 * @param activity 엑티비티
	 */
	public BaseListHandler(Activity activity)
	{
		this.mParentActivity = activity;
		this.mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		this.mFlagListView = true;
		this.mIsLoadedHeaderView = false;
	}
	
	/**
	 * 헤더뷰를 정의합니다.
	 * 
	 * @param headerView 헤더뷰
	 */
	public final void setHeaderView(View headerView)
	{
		this.mHeaderView = headerView;
	}
	
	/**
	 * 푸터뷰를 정의합니다.
	 * 
	 * @param footerView 푸터뷰
	 */
	public final void setFooterView(View footerView)
	{
		this.mFooterView = footerView;
	}
	
	/**
	 * 현재 화면에 사용되는 엑티비티를 반환합니다.
	 * 
	 * @return 엑티비티
	 */
	public final Activity getActivity()
	{
		return mParentActivity;
	}
	
	/**
	 * 리소스아이디를 이용하여 뷰를 생성한다.
	 * 
	 * @param resId 리소스 아이디
	 * @return 생성된 뷰
	 */
	public final View inflate(int resId)
	{
		return mInflater.inflate(resId, null);
	}
	
	/**
	 * 리스트뷰 객체를 설정한다.
	 * 
	 * @param listView 리스트뷰
	 */
	public final void setListView(BaseListView listView)
	{
		this.mListView = listView;
	}
	
	/**
	 * 리스트를 표현하는데 사용되는 어댑터 객체를 설정한다.
	 * 
	 * @param listAdapter 리스트어댑터
	 */
	public final void setListAdapter(BaseListAdapter listAdapter)
	{
		this.mListAdapter = listAdapter;
	}
	
	/**
	 * 리스트를 초기화 한다.
	 */
	public final void refresh()
	{
		mFlagListView = true;
		mListView.setSelection(0);
		onRowClear();
		mListAdapter.notifyDataSetChanged();
		loadContent();
	}
	
	/**
	 * 리스트 상단의 헤더뷰를 가져온다.
	 * 
	 * @return 헤더뷰
	 */
	public View getHeaderView()
	{
		return null;
	}
	
	/**
	 * 리스트 하단의 푸터뷰를 가져온다.
	 * 
	 * @return 푸터뷰
	 */
	public View getFooterView()
	{
		return null;
	}
	
	/**
	 * 데이터의 변경을 리스트뷰에 실제 적용합니다.
	 */
	public synchronized void notifyDataSetChanged()
	{
		synchronized(mListAdapter)
		{
			mListAdapter.notifyDataSetChanged();
		}
	}
	
	@Override
	public final void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
	{
		// 현재 가장 처음에 보이는 셀번호와 보여지는 셀번호를 더한값이 전체의 숫자와 동일해지면 가장 아래로 스크롤 되었다고
		// 가정합니다.
		int count = totalItemCount - visibleItemCount;

		if(firstVisibleItem >= count && totalItemCount != 0 && mFlagListView == false)
		{
			synchronized(mListAdapter)
			{
				mFlagListView = !mFlagListView;
				loadContent();
			}
		}
	}
	
	@Override
	public final void onScrollStateChanged(AbsListView view, int position)
	{
		
	}
	
	/**
	 * 자동으로 리스트를 추가할지 여부를 결정하는 변수값을 반전시킵니다.
	 */
	public void toggleLockListView()
	{
		mFlagListView = !mFlagListView;
	}
	
	/**
	 * 새로운 액티비티를 생성한다.
	 * 
	 * @return 액티비티 관리자
	 */
	public ActivityUtil getNewActivity()
	{
		return new ActivityUtil(mParentActivity);
	}
	
	/**
	 * 리스트뷰에 어댑터를 세팅한다. 이것을 수행하기 전에 헤더와 푸터가 붙어있어야 한다.
	 */
	public void setAdapter()
	{
		mListView.setAdapter(mListAdapter);
	}
	
	/**
	 * 간편하게 사용할 수 있는 AlertDialog 메시지창
	 * 
	 * @param message 출력할 메시지
	 */
	protected void alert(String message)
	{
		MessageUtil.alert(mParentActivity, message);
	}
	
	/**
	 * 간편하게 사용할 수 있는 Toast 메시지 창
	 * 
	 * @param message 출력할 메시지
	 */
	protected void toast(String message)
	{
		MessageUtil.toast(mParentActivity, message);
	}
	
	/**
	 * 푸터뷰를 삭제합니다. 
	 */
	protected void removeFooterView()
	{
		try
		{
			if(mFooterView != null)
			{
				mListView.removeFooterView(mFooterView);
				mFooterView = null;
			}
		}
		catch(Exception e)
		{
			mFooterView.setVisibility(View.GONE);
		}
	}
	
	/**
	 * 설정된 헤더뷰를 보여줍니다.
	 */
	public final void showHeaderView()
	{
		if(mHeaderView != null)
		{
			if(!mIsLoadedHeaderView)
			{
				mListView.addHeaderView(mHeaderView);
				mIsLoadedHeaderView = true;
			}
		}
		else
		{
			Log.w(TAG, "헤더뷰가 정의되지 않았습니다.");
		}
	}
	
	/**
	 * 헤더뷰를 보여줍니다.
	 */
	public final void showHeaderView(View headerView)
	{
		if(!mIsLoadedHeaderView)
		{
			mListView.addHeaderView(headerView);
			mIsLoadedHeaderView = true;
		}
	}
	
	/**
	 * 설정된 푸터뷰를 보여줍니다.
	 */
	public final void showFooterView()
	{
		if(mFooterView != null)
		{
			mListView.addFooterView(mFooterView);
		}
		else
		{
			Log.w(TAG, "푸터뷰가 정의되지 않았습니다.");
		}
	}
	
	/**
	 * 푸터뷰를 보여줍니다.
	 */
	public final void showFooterView(View footerView)
	{
		mListView.addFooterView(footerView);
	}
	
	public abstract ArrayList<?> getArrayList();
	public abstract View getRowView(int position, View convertView);
	public abstract void onRowClick(View v);
	public abstract void onRowClear();
	public abstract void loadContent();
	public abstract void onInit();
}
